package main;

import java.util.Stack;

/**
 *    棋盘数据结构
 *    主要用于实现五子棋中和数据有关的功能
 */
public class Core {
    //棋盘大小
    private int[][] cc;//设定棋盘为一个二维数组
    private int x;       //棋盘中的点坐标用(x,y)来表示
    private int y;
    //栈
    Stack<Chess> stack;  //使用栈来存储棋盘中位置的棋子类型
    //构造方法
    public Core(int x,int y) {
        stack = new Stack<>();
        cc = new int[x][y];
        this.x=x;
        this.y=y;
    }
    //检查该地是否有空位置
    private boolean __CanInput(int x,int y) {//检测是否可以下棋
        if(cc[x][y]==0) return true;       //可以则返回true
        else return false;                 //不可以则返回false
    }
    //判断输赢
    private int checkVictory(int x,int y,int bb) {
        //横向判断
        int flag = 0;                      //看是否会自增5次
        for(int i=x-4;i<x+5;i++) {
            if(i<0||i>=this.x) continue;
            if(cc[i][y]==bb) {
                flag++;
            }
            else {
                flag=0;
            }
            if(flag==5) return bb;
        }
        //纵向判断
        int bubble = 0;
        for(int i=y-4;i<y+5;i++) {
            if(i<0||i>=this.y) continue;
            if(cc[x][i]==bb) {
                bubble++;
            }
            else {
                bubble=0;
            }
            if(bubble==5) return bb;
        }
        //从左上到右下
        int leftUPToDown = 0;
        for(int i=x-4,j=y+4;i<x+5&&j>y-5;i++,j--) {
            if(i<0||i>=this.x||j<0||j>=this.y) continue;
            if(cc[i][j]==bb) {
                leftUPToDown++;
            }else {
                leftUPToDown=0;
            }
            if(leftUPToDown==5) return bb;
        }
        //从左下到右上
        int leftDownToUP = 0;
        for(int i=x+4,j=y+4;i>x-5&&j>y-5;i--,j--) {
            if(i<0||i>=this.x||j<0||j>=this.y) continue;
            if(cc[i][j]==bb) {
                leftDownToUP++;
            }else {
                leftDownToUP=0;
            }
            if(leftDownToUP==5) return bb;
        }
        return 0;
    }
    /**
     * 在该位置下棋  1:white 2:black
     *  x 横坐标
     *  y 纵坐标
     *  bb 棋子种类
     *  1:white 赢   2:black赢
     */
    //悔棋之前用于存储棋子的信息
    public int ChessIt(int x,int y,int bb) {
        if(__CanInput(x,y)) {               //如果此处可以下棋为真
            cc[x][y] =bb;                //令此处信息储存为bb
            Chess chess = new Chess(x,y);   //新建一个棋子对象
            stack.push(chess);              //下棋，则入栈
            return checkVictory(x, y, bb); //返回值同时判断是否有人赢了
        }
        else return -1;
    }
    //悔棋
    public boolean HuiQi() {
        if(stack.isEmpty()) return false;//栈空说明棋盘上没有棋
        Chess chess = stack.pop();       //悔棋则出栈
        cc[chess.x][chess.y]= 0;       //令该位置存储的信息为零代表没有棋子
        return true;                     //返回值为true，代表悔棋成功
    }
    //获得棋盘状态
    public int[][] getCore(){
        return this.cc;
    }
    //重新开始
    public void Restart() {//重新开始
        for(int i=0;i<this.x;i++) {//循环令每一个坐标储存的棋子信息为空
            for(int j=0;j<this.y;j++) {
                this.cc[i][j]=0;
            }
        }
        this.stack.clear();         //清除栈中内容
    }
}